// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET.
// Licensed under the Apache License, Version 2.0.

#if Q8
using QuantumType = System.Byte;
#elif Q16
using QuantumType = System.UInt16;
#elif Q16HDRI
using QuantumType = System.Single;
#else
#error Not implemented!
#endif

namespace ImageMagick
{
    /// <summary>
    /// Encapsulation of the DrawableCompositeImage object.
    /// </summary>
    public sealed class DrawableComposite : IDrawable, IDrawingWand
    {
        private readonly IMagickImage<QuantumType> _image;

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawableComposite"/> class.
        /// </summary>
        /// <param name="x">The X coordinate.</param>
        /// <param name="y">The Y coordinate.</param>
        /// <param name="image">The image to draw.</param>
        public DrawableComposite(double x, double y, IMagickImage<QuantumType> image)
          : this(x, y, CompositeOperator.In, image)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawableComposite"/> class.
        /// </summary>
        /// <param name="x">The X coordinate.</param>
        /// <param name="y">The Y coordinate.</param>
        /// <param name="compose">The algorithm to use.</param>
        /// <param name="image">The image to draw.</param>
        public DrawableComposite(double x, double y, CompositeOperator compose, IMagickImage<QuantumType> image)
          : this(image)
        {
            X = x;
            Y = y;
            Width = _image.Width;
            Height = _image.Height;
            Compose = compose;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawableComposite"/> class.
        /// </summary>
        /// <param name="offset">The offset from origin.</param>
        /// <param name="image">The image to draw.</param>
        public DrawableComposite(IMagickGeometry offset, IMagickImage<QuantumType> image)
          : this(offset, CompositeOperator.In, image)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawableComposite"/> class.
        /// </summary>
        /// <param name="offset">The offset from origin.</param>
        /// <param name="compose">The algorithm to use.</param>
        /// <param name="image">The image to draw.</param>
        public DrawableComposite(IMagickGeometry offset, CompositeOperator compose, IMagickImage<QuantumType> image)
          : this(image)
        {
            Throw.IfNull(nameof(offset), offset);

            X = offset.X;
            Y = offset.Y;
            Width = offset.Width;
            Height = offset.Height;
            Compose = compose;
        }

        private DrawableComposite(IMagickImage<QuantumType> image)
        {
            Throw.IfNull(nameof(image), image);

            _image = image;
        }

        /// <summary>
        /// Gets or sets the composition operator.
        /// </summary>
        public CompositeOperator Compose { get; set; }

        /// <summary>
        /// Gets or sets the height to scale the image to.
        /// </summary>
        public double Height { get; set; }

        /// <summary>
        /// Gets or sets the width to scale the image to.
        /// </summary>
        public double Width { get; set; }

        /// <summary>
        /// Gets or sets the X coordinate.
        /// </summary>
        public double X { get; set; }

        /// <summary>
        /// Gets or sets the Y coordinate.
        /// </summary>
        public double Y { get; set; }

        /// <summary>
        /// Draws this instance with the drawing wand.
        /// </summary>
        /// <param name="wand">The want to draw on.</param>
        void IDrawingWand.Draw(DrawingWand wand)
            => wand?.Composite(X, Y, Width, Height, Compose, _image);
    }
}
